package cn.buddha.jec.util;

import cn.buddha.jec.constants.TongConstant;
import cn.buddha.jec.exception.enums.TongExceptionEnum;
import io.swagger.annotations.ApiModelProperty;
import org.hibernate.validator.HibernateValidator;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.Set;

/**
 * @ClassName TongValidatorUtils
 * @Author 友野浩二
 * @Description 接口controller数据校验工具类
 * @Version 1.0
 */
public class TongValidatorUtils {

    /**
     * 使用HibernateValidator
     */
    private static Validator validator = Validation.byProvider(HibernateValidator.class).configure()
            .failFast(true)
            .buildValidatorFactory()
            .getValidator();

    public static Validator getValidator() {
        return validator;
    }

    /**
     * @Author 友野浩二
     * @Description // 接口上送模型校验
     * @Param [t, validator]
     * @return void
     *
     * public 与 返回值中间<T>非常重要，可以理解为声明此方法为泛型方法。
     */
    public static <T> void validateRequest(T t, Validator validator) {
        // 对入参对象作校验,如果校验成功,则返回的 ConstraintViolation 类型的集合为空,否则该集合为空;
        // 集合中的每一个元素(ConstraintViolation 类型)对应一个违反的约束。
        Set<ConstraintViolation<T>> constraintViolationSet = validator.validate(t);
        if (!TongBeanUtils.isNullObj(constraintViolationSet)) {
            ConstraintViolation<T> violationInfo = constraintViolationSet.iterator().next();

            StringBuffer messageStrBuff = new StringBuffer();
            try {
                ApiModelProperty apiModelProperty = violationInfo.getRootBeanClass()
                        .getDeclaredField(violationInfo.getPropertyPath().toString())
                        .getAnnotation(ApiModelProperty.class);
                String className = violationInfo.getRootBeanClass().getSimpleName();
                messageStrBuff.append("[");
                if (TongConstant.TONG_IN_HEAD.equals(className)) {
                    messageStrBuff.append(className).append(".");
                }
                // 属性名 + swagger的ApiModelProperty.value(属性说明) + 异常信息
                messageStrBuff.append(violationInfo.getPropertyPath().toString()).append(", ")
                        .append(apiModelProperty == null ? "" : apiModelProperty.value()).append("]")
                        .append(violationInfo.getMessage());
            } catch (NoSuchFieldException e) {
                messageStrBuff.append(violationInfo.getMessage());
            }
            // API接口数据校验的错误码统一为TH000
            throw TongBusinessUtils.createBusinessException(TongExceptionEnum.TRAN_ERROR.getCode(), messageStrBuff.toString());
        }
    }

}
